package com.aliothservice.catfish.message.data;

import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import com.mongodb.WriteResult;

public class MessageDataManager {
	
	public MessageHub findMessageHubByPhoneNumber(String phoneNumber) {
		Query query = new Query();
		Criteria criteria = Criteria.where("phoneNumber").is(phoneNumber);
		query.addCriteria(criteria);
		
		return mongoTemplate.findOne(query, MessageHub.class);
	}
	
	public void readMessages(String phoneNumber, List<String> idList) {
		// locate message hub
		MessageHub hub = findMessageHubByPhoneNumber(phoneNumber);
		if (null == hub) {
			return;
		}
		if (null == hub.getUnreadMessages()) {
			if (logger.isWarnEnabled()) {
				logger.warn("readMessages - invalid state, mark message as read, but no unread messages, phone number: " + phoneNumber);
			}
			return;
		}
		
		// mark messages as read
		List<Message> unreadList = hub.getUnreadMessages();
		List<Message> readList = hub.getReadMessages();
		if (null == readList) {
			readList = new ArrayList<Message>();
		}
		for (String id : idList) {
			for (Message unread : unreadList) {
				if (0 == id.compareTo(unread.getId())) {
					unreadList.remove(unread);
					readList.add(0, unread);
					break;
				}
			}
		}
		
		// update hub
		Query query = new Query();
		Criteria criteria = Criteria.where("phoneNumber").is(phoneNumber);
		query.addCriteria(criteria);
		Update update = new Update();
		update.set("readMessages", readList);
		update.set("unreadMessages", unreadList);
		mongoTemplate.updateFirst(query, update, MessageHub.class);
	}
	
	public boolean deleteMessages(String phoneNumber, List<String> idList) {
		// locate message hub
		MessageHub hub = findMessageHubByPhoneNumber(phoneNumber);
		if (null == hub) {
			return false;
		}
		
		List<Message> unreadList = hub.getUnreadMessages();
		List<Message> readList = hub.getReadMessages();
		for (String messageId : idList) {
			for (Message message : unreadList) {
				if (0 == message.getId().compareTo(messageId)) {
					unreadList.remove(message);
					break;
				}
			}
			for (Message message : readList) {
				if (0 == message.getId().compareTo(messageId)) {
					readList.remove(message);
					break;
				}
			}
		}
		Query query = new Query();
		Criteria userCriteria = Criteria.where("phoneNumber").is(phoneNumber);
		query.addCriteria(userCriteria);
		Update update = new Update();
		update.set("readMessages", readList);
		update.set("unreadMessages", unreadList);
		
		WriteResult result = mongoTemplate.updateFirst(query, update, MessageHub.class);
		if (logger.isDebugEnabled()) {
			logger.debug("deleteMessages - n: " + result.getN());
		}
		
		return true;
	}
	
	public void postMessage(Message message, String phoneNumber) {
		Query query = new Query();
		Criteria criteria = Criteria.where("phoneNumber").is(phoneNumber);
		query.addCriteria(criteria);
		
		Update update = new Update();
		update.set("phoneNumber", phoneNumber);
		update.addToSet("unreadMessages", message);
		
		mongoTemplate.upsert(query, update, MessageHub.class);
	}
	
	@Autowired
	private MongoTemplate mongoTemplate;

	private static final Logger logger = LoggerFactory.getLogger(MessageDataManager.class);
	
}
